import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import java.awt.image.*;

public class Somatochart {
	public Somatochart()
	{
		points = new ArrayList<Point2D>(5);
		labelPoints = new ArrayList<String>(5);
		scale = 30;
		panelG = new PanelGraph();
	}
	public void clear()
	{
		points.clear();
		labelPoints.clear();
		panelG.repaint();
		panelG.revalidate();
	}
	public void update()
	{
		panelG.repaint();
		panelG.revalidate();
	}
	public int getScale()
	{
		return scale;
	}
	public JPanel getPanel()
	{
		return panelG;
	}
	public void setScale(int scale_)
	{
		scale = scale_;
		panelG.repaint();
		panelG.revalidate();
	}
	public BufferedImage getImage(int scale_)
	{
		scale = scale_;
		return getImage();
	}
	public BufferedImage getImage()
	{
		BufferedImage imgGraph = new BufferedImage(
				1600*scale/100,
				1600*scale/100,
	            BufferedImage.
	            TYPE_INT_ARGB);
		Graphics2D g2 = imgGraph.createGraphics();
		paintGraph(g2);
		paintPoints(g2);
		return imgGraph;
	}
	public void setPoints(ArrayList<Point2D> points_,ArrayList<String> labels)
	{
		points = points_;
		labelPoints = labels;
	}
	public void addPoint(Point2D point,String label)
	{
		points.add(point);
		labelPoints.add(label);
	}
	public void addPoint(int point_x, int point_y,String label)
	{
		points.add(new Point(point_x,point_y));
		labelPoints.add(label);
	}
	public void addPoint(float point_x, float point_y,String label)
	{
		points.add(new Point2D.Float(point_x,point_y));
		labelPoints.add(label);
	}
	public void addPoint(double point_x, double point_y,String label)
	{
		points.add(new Point2D.Double(point_x,point_y));
		labelPoints.add(label);
	}
	public void addPoint(
            double endomorphy, 
            double mesomorphy, 
            double ectomorphy,
            String label)
    {
		double x = (double)(ectomorphy - endomorphy);
		double y = (double)((2*mesomorphy) - (ectomorphy + endomorphy));
        points.add(new Point2D.Double(x,y));
        labelPoints.add(label);
    }
	private void paintPoints(Graphics2D g2)
	{
		for(int i = 0; i < points.size(); i++)
		{
            g2.fill(getPoint(points.get(i)));
            Point2D point = translation(points.get(i));
            g2.drawString(
            		labelPoints.get(i),
                    (float)(point.getX()+radius/2)*scale,
                    (float)(point.getY()-radius/2)*scale);
		}
	}
	private void paintGraph(Graphics2D g2)
    {
        radius = 0.3F;
        /*imgGraph = new BufferedImage(
            480,
            480,
            BufferedImage.
            TYPE_INT_ARGB);*/
        //g2 = imgGraph.createGraphics();
        g2.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(Color.BLACK);
        g2.setBackground(Color.WHITE);
        //g2.scale(0.5,0.5);
        g2.setStroke(
            new BasicStroke(0.09F,
            BasicStroke.CAP_ROUND,
            BasicStroke.JOIN_ROUND));
        Arc2D arcLeft = getArc2DFloat(
            2,
            0.7017F,
            24,
            24,
            120,
            60,
            Arc2D.OPEN
        );
        Arc2D arcRight = getArc2DFloat(
            -10,
            0.7017F,
            24,
            24,
            0,
            60,
            Arc2D.OPEN
        );
        Arc2D arcBottom = getArc2DFloat(
            -4,
            -9.6905F,
            24,
            24,
            240,
            60,
            Arc2D.OPEN
        );
        g2.draw(arcRight);
        g2.draw(arcLeft);
        g2.draw(arcBottom);
        g2.setFont(new Font("SansSerif",Font.BOLD,(int)(40*scale/100)));
        g2.drawString(
            Resources.getString("mesomorphy"),
            6*scale,
            2*scale);
        g2.drawString(
            Resources.getString("endomorphy"),
            0.5F*scale,
            14*scale);
        g2.drawString(
            Resources.getString("ectomorphy"),
            12*scale,
            14*scale);
        g2.draw(getLine2DFloat(//ENDOMORFISMO Line
            (float)(8F*Ux),
            (float)(16F*Uy),
            (float)(2*Ux),
            (float)(22*Uy)));
        g2.draw(getLine2DFloat(//ECTOMORFISMO Line
            (float)(8F*Ux),
            (float)(16F*Uy),
            (float)(14*Ux),
            (float)(22*Uy)));
        g2.draw(getLine2DFloat(//MESOMORFISMO Line
            (float)(8F*Ux),
            (float)(16F*Uy),
            (float)(8*Ux),
            (float)(4*Uy)));
    }
	private Ellipse2D getPoint(Point2D point)
    {
        Point2D point_aux = translation(point);
        return getEllipse2DFloat(
            (float)point_aux.getX()-radius/2,
            (float)point_aux.getY()-radius/2,
            radius,
            radius);
    }
    private Point2D translation(Point2D point)
    {
        return new Point2D.Double(
            (double)((ORIGIN.getX()+point.getX())*Ux),
            (double)((ORIGIN.getY()-point.getY())*Uy)
        );
    }
    private Arc2D getArc2DFloat(
            float x,
            float y,
            float w,
            float h,
            float start,
            float extent,
            int type)
    {
        return new Arc2D.Float(
                x*scale,
                y*scale,
                w*scale,
                h*scale,
                start,
                extent,
                type
            );
    }
    private Ellipse2D getEllipse2DFloat(
        float x,
        float y,
        float w,
        float h)
    {
        return new Ellipse2D.Float(
            x*scale,
            y*scale,
            w*scale,
            h*scale);
    }
    private Line2D getLine2DFloat(
        float x1,
        float y1,
        float x2,
        float y2)
    {
        return new Line2D.Float(
            x1*scale,
            y1*scale,
            x2*scale,
            y2*scale);
    }
    private class PanelGraph extends JPanel
    {
    	public PanelGraph()
    	{
    		super();
    		Border etched = BorderFactory.createEtchedBorder();
    		this.setBackground(Color.WHITE);
    		//this.setMaximumSize(new Dimension(300, 300));
    		/*MouseMotionListener doScrollRectToVisible = new 
				MouseMotionAdapter() 
    			{
	    		     public void mouseDragged(MouseEvent e) {
	    		        Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
	    		        ((JPanel)e.getSource()).scrollRectToVisible(r);
	    		    }
    			};
    		this.addMouseMotionListener(doScrollRectToVisible);
    		this.setAutoscrolls(true);*/
    	}
    	public void paintComponent(Graphics g)
    	{
    		super.paintComponent(g);
    		this.setPreferredSize(new Dimension(1600*scale/100, 1600*scale/100));
    		paintGraph((Graphics2D) g);
    		paintPoints((Graphics2D) g);
    	}
    }
    private PanelGraph panelG;
    private ArrayList<Point2D> points;
    private ArrayList<String> labelPoints;
    private float radius;
    private int scale;
    //private BufferedImage imgGraph;
    private static final Point2D ORIGIN = new Point2D.Float(8,16);
    private static final Double Ux = new Double(1);
    private static final Double Uy = new Double(Ux/Math.sqrt(3));//0.577350269);
}
